package com.wei.frame.framework;

import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

import com.wei.frame.utils.Preconditions;

import java.lang.ref.WeakReference;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;

/**
 * 作者：赵若位
 * 时间：2020/8/20 3:06
 * 邮箱：1070138445@qq.com
 * 功能：
 */
public class BasePresenter<M extends BaseModel, V extends IView> implements IPresenter, LifecycleObserver {
    protected static final String TAG = BasePresenter.class.getSimpleName();
    private M mModel;
    private V mView;
    private CompositeDisposable mDisposable;
    private WeakReference<V> mWeakReference;


    public BasePresenter(@Nullable M model, @Nullable V view) {
        mModel = Preconditions.checkNotNull(model, "%s cannot be null~", model.getClass().getName());
        mView = Preconditions.checkNotNull(view, "%s cannot be null~", view.getClass().getName());
        onCreate();
    }

    public BasePresenter(@Nullable V view) {
        this.mView = Preconditions.checkNotNull(view, "%s cannot be null~", view.getClass().getName());
        onCreate();
    }

    @Override
    public void onCreate() {
        mWeakReference = new WeakReference<V>(mView);
    }

    @Override
    public void onDestroy() {
        unDisposable();
        mWeakReference.clear();
        this.mView = null;
        this.mModel = null;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestory(LifecycleOwner owner) {
        /**
         * 注意, 如果在这里调用了 {@link #onDestroy()} 方法, 会出现某些地方引用 {@code mModel} 或 {@code mRootView} 为 null 的情况
         * 比如在 {@link RxLifecycle} 终止 {@link Observable} 时, 在 {@link io.reactivex.Observable#doFinally(Action)} 中却引用了 {@code mRootView} 做一些释放资源的操作, 此时会空指针
         * 或者如果你声明了多个 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 时在其他 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
         * 中引用了 {@code mModel} 或 {@code mRootView} 也可能会出现此情况
         */
        onDestroy();
        if (null != owner) {
            owner.getLifecycle().removeObserver(this);
        }
    }

    protected final void addDisposable(@Nullable Disposable disposable) {
        if (null == mDisposable) {
            mDisposable = new CompositeDisposable();
        }
        if (null != disposable) {
            mDisposable.add(disposable);
        }
    }

    protected final void unDisposable() {
        if (null != mDisposable) {
            mDisposable.clear();
            mDisposable = null;
        }
    }

}
